﻿package eu.liquify.ui {
	import flash.display.DisplayObject;
	import flash.display.InteractiveObject;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.Graphics;
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.filters.BevelFilter;
	import flash.filters.DropShadowFilter;
	import flash.filters.GlowFilter;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.ui.Keyboard;
	public class Button extends Label implements IHasBindValue {
		public static const NORMAL:String = "normal";
		public static const TOGGLE:String = "toggle";
		
		public var type:String = NORMAL;
		
		public var click:Function = NULL_FUNCTION;
		
		public var animate:Boolean = true;
		
		private var _handleEvents:Boolean;
		
		private var _toggle:Boolean = false;
		private var _selected:Boolean = false;
		private var rotationContainer:Sprite;
		private var contentContainer:Sprite;
		private var txtContainer:Sprite;
		protected var background:Sprite;
		
		private var _trans:Number;
		
		private var animating:Boolean = false;
		
		protected var bevel:BevelFilter = new BevelFilter(8, 45, 0xAFC5FE, 0.6, 0x435089, 0.6, 16, 16, 1, 3);
		protected var shadow:DropShadowFilter = new DropShadowFilter(3, 45, 0x4477FD, 0.3, 4, 4);
		
		private var previousFocus:InteractiveObject;
		
		public function Button(options:Object = null) {
			fixedSize = true;
			
			rotationContainer = new Sprite();
			addChild(rotationContainer);
			contentContainer = new Sprite();
			rotationContainer.addChild(contentContainer);
			
			background = new Sprite();
			contentContainer.addChild(background);
			
			super(options);
			
			removeChild(txt);
			
			txtContainer = new Sprite();
			txtContainer.mouseChildren = txtContainer.mouseEnabled = false;
			contentContainer.addChild(txtContainer);
			txtContainer.addChild(txt);
			
			txt.defaultTextFormat = new TextFormat(null, null, 0xFFFFFF, true);
			//txt.defaultTextFormat = new TextFormat(null, null, 0xFFFFFF, true);
			//txt.defaultTextFormat = new TextFormat(null, 10, 0xFFFFFF, true);
			//txt.defaultTextFormat = new TextFormat(null, 10, 0xFFFFFF);
			//txt.defaultTextFormat = new TextFormat("Tahoma", 9, 0xFFFFFF, true); txt.embedFonts = false;
			//txt.defaultTextFormat = new TextFormat("Segoe UI", 10, 0xFFFFFF, true);
			//txt.defaultTextFormat = new TextFormat("Thebuchet MS", 10, 0xFFFFFF, true);
			//txt.embedFonts = false;
			//txt.sharpness = -400;
			ellipsisFormat = new TextFormat(null, null, 0xDDE0E8);
			
			background.buttonMode = true;
			//background.filters = [new BevelFilter(8, 45, 0xFFFFFF, 0.5, 0x000000, 0.5, 16, 16, 1, 3), new GlowFilter(0x4477FD, 1, 8, 8, 2, 3)];
			//background.filters = [new BevelFilter(8, 45, 0x92AFFE, 0.8, 0x5665AD, 0.8, 16, 16, 1, 3), new DropShadowFilter(3, 45, 0x4477FD, 0.3, 4, 4)];
			background.filters = [bevel, shadow];
			//background.filters = [new BevelFilter(8, 45, 0x92AFFE, 0.8, 0x5665AD, 0.8, 16, 16, 1, 3)];
			handleEvents = true;
			
			tabEnabled = true;
			
			width = 70; height = 21;
			//width = 70; height = 30;
			trans = 0.8;
			resize();
		}
		
		public function get trans():Number { return _trans; }
		
		public function set trans(value:Number):void {
			_trans = value;
			redraw();
		}
		
		public function get handleEvents():Boolean { return _handleEvents; }
		
		public function set handleEvents(value:Boolean):void {
			_handleEvents = value;
			if (handleEvents) {
				background.addEventListener(MouseEvent.ROLL_OVER, rollOver);
				background.addEventListener(MouseEvent.ROLL_OUT, rollOut);
				background.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
				background.addEventListener(MouseEvent.CLICK, mouseClick);
				addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
				background.addEventListener(FocusEvent.FOCUS_IN, focusIn);
			} else {
				background.removeEventListener(MouseEvent.ROLL_OVER, rollOver);
				background.removeEventListener(MouseEvent.ROLL_OUT, rollOut);
				background.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
				background.removeEventListener(MouseEvent.CLICK, mouseClick);
				removeEventListener(KeyboardEvent.KEY_DOWN, keyDown);
				background.removeEventListener(FocusEvent.FOCUS_IN, focusIn);
			}
		}
		
		private function keyDown(e:KeyboardEvent):void {
			if (e.keyCode == Keyboard.ENTER || e.keyCode == Keyboard.SPACE) simulateClick();
		}
		
		public function simulateClick():void {
			mouseDown();
			mouseUp();
			mouseClick();
		}
		
		/**
		 * Restores focus to the previously focused object
		 * @param	e
		 */
		private function focusIn(e:FocusEvent):void {
			stage.focus = e.relatedObject;
		}
		
		private function mouseDown(e:MouseEvent = null):void {
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
			TweenNano.to(txtContainer, 0.1, { x: 0, y: 1 } );
			TweenNano.to(bevel, 0.1, { angle: 225, onUpdate: redraw } );
		}
		
		private function mouseUp(e:MouseEvent = null):void {
			stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
			TweenNano.to(txtContainer, 0.1, { x: 0, y: 0 } );
			TweenNano.to(bevel, 0.1, { angle: 405, onUpdate: redraw } );
		}
		
		private function mouseClick(e:MouseEvent = null):void {
			if (toggle) selected = !selected;
			
			Utils.callDynamic(click, this);
		}
		
		public function get bindValue():Object { return selected; }
		public function set bindValue(value:Object):void { selected = Boolean(value); }
		public function get selected():Boolean { return _selected; }
		
		public function set selected(value:Boolean):void {
			var change:Boolean = value != selected;
			_selected = value;
			if (change) {
				TweenNano.killTweensOf(rotationContainer);
				resetContainer();
				animating = false;
				
				if (animate) {
					animating = true;
					
					//rotationContainer.width -= 1;
					//rotationContainer.height -= 1;
					rotationContainer.scaleX = rotationContainer.scaleY = (rotationContainer.width-1)/rotationContainer.width;
					var time:Number = 0.5;
					TweenNano.to(rotationContainer, time/2, { ease: Cubic.easeIn, rotationX: 180,
						onComplete: function():void {
							redrawToggle();
					
							TweenNano.to(rotationContainer, time/2, { ease: Cubic.easeOut, overwrite: false, rotationX: 360,
								onComplete: function():void {
									TweenNano.killTweensOf(rotationContainer);
									resetContainer();
									animating = false;
									//ConsoleUtil.print(label+" AFTER");
								}
							} );
						}
					} );
				} else {
					redrawToggle();
				}
				
			}
		}
		
		private function resetContainer():void {
			rotationContainer.transform.matrix3D = null;
			rotationContainer.transform.matrix = new Matrix(1, 0, 0, 1, -contentContainer.x, -contentContainer.y);
		}
		
		public function get toggle():Boolean { return _toggle; }
		
		public function set toggle(value:Boolean):void {
			_toggle = value;
			if (!toggle) selected = false;
			redrawToggle();
		}
		
		private function rollOver(e:MouseEvent):void {
			if (animating) return;
			//rotationContainer.width -= 1;
			//rotationContainer.height -= 1;
			//rotationContainer.z = 1;
			//rotationContainer.z = 0;
			//TweenNano.to(rotationContainer, 0.2, { scaleX: 0.9, scaleY: 0.9 } );
			//redraw(toggle ? (selected ? 0.6 : 0.8) : 1);
		}
		
		private function rollOut(e:MouseEvent):void {
			if (animating) return;
			//TweenNano.to(rotationContainer, 0.2, { scaleX: 1, scaleY: 1 } );
			//TweenNano.to(rotationContainer, 0.2, { z: 0, onComplete: resetContainer } );
			//redraw(toggle ? (selected ? 1 : 0.5) : 0.8);
		}
		
		private function redrawToggle():void {
			trans = selected ? 1 : 0.5;
		}
		
		override public function resize():void {
			super.resize();
			txt.y += 1;
			redraw();
		}
		
		protected function redraw(draw:Boolean = true):void {
			if (draw) {
				background.filters = [bevel, shadow];
				var g:Graphics = background.graphics;
				g.clear();
				//g.lineStyle(0, 0x022D9D, 0.1, true);
				g.beginFill(0xFFFFFF);
				g.drawRoundRect(0, 0, width, height, 6, 6);
				g.beginFill(0x4477FD, trans);
				g.drawRoundRect(0, 0, width, height, 6, 6);
			}
			
			contentContainer.x = -contentContainer.width/2;
			contentContainer.y = -contentContainer.height/2;
			rotationContainer.x = -contentContainer.x;
			rotationContainer.y = -contentContainer.y;
		}
		
	}
	
}